package com.ala4.oxcafe.boot.handler;

import com.ala4.oxcafe.boot.dto.TokenDTO;
import com.ala4.oxcafe.boot.event.UserLoginEvent;
import com.ala4.oxcafe.boot.manager.CustomUserDetails;
import com.ala4.oxcafe.boot.manager.UserTokenManager;
import com.ala4.oxcafe.common.utils.IpAddressUtil;
import com.ala4.oxcafe.common.utils.ResponseWriter;
import com.ala4.oxcafe.common.utils.event.SpringEventUtil;
import com.ala4.oxcafe.common.utils.object.ObjectUtil;
import com.ala4.oxcafe.domain.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;
import java.time.LocalDateTime;

/**
 * 登录成功处理类
 *
 * @author PING
 * @version 1.0
 * @date 2024/12/24 16:06
 */
@Slf4j
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    private final UserTokenManager userTokenManager;

    public LoginSuccessHandler(UserTokenManager userTokenManager) {
        this.userTokenManager = userTokenManager;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        log.info("登录成功:{}", authentication);
        TokenDTO token = null;
        if (authentication.getPrincipal() instanceof CustomUserDetails customUserDetails) {
            // 创建token
            token = userTokenManager.createToken(customUserDetails);
        }

        // 这里兼容内存模式返回的user的情况
        if (authentication.getPrincipal() instanceof User user) {
            // 创建token
            token = userTokenManager.createToken(user);
        }

        if (ObjectUtil.isNull(token)) {
            throw new UsernameNotFoundException("登录失败,无法找到对应的用户类型[" + authentication.getClass().toString() + "]");
        }

        String clientIp = IpAddressUtil.getClientIp(request);

        // 用户登录成功事件
        SpringEventUtil.publishEvent(new UserLoginEvent(token.getUserId(), LocalDateTime.now(), clientIp));

        ResponseWriter.write(response, R.ok(token));
    }
}
